package com.guldan.core.utils;

/**
 * Created by Silas.
 * Date: 2016/10/1
 * Time: 22:22
 */

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;

public final class DateUtil {
    public static final String DAY_FORMAT = "yyyyMMdd";
    public static final String MONTH_FORMAT = "yyyyMM";
    public static final String YYYY_MM_DD = "yyyy/MM/dd";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String YYYY_MM_DD_CN = "yyyy年MM月dd日";
    public static final String YYYY_MM_CN = "yyyy年MM月";
    public static final String YYYY_MM_DD_HH_DD_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDDHHDDSS = "yyyyMMddHHmmss";
    public static final String YYYYMMDDHHDDSS_S = "yyyyMMddHHmmssS";
    public static final String YYYY_MM_DD_HH_DD = "yyyy-MM-dd HH:mm";
    public static final String YY_MM = "yy-MM";
    public static final String MM_DD = "MM-dd";
    public static final String HH_MI = "HH:mm";
    public static final String MM_DD_HH_MI = "MM-dd HH:mm";

    private DateUtil() {
    }

    public static Date getCurrentTime() {
        return Calendar.getInstance().getTime();
    }

    public static String toLocaleString(Date date) {
        return toLocaleString(date, (String) null);
    }

    public static String getNowTime() {
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date(System.currentTimeMillis()));
    }

    public static String getDateTimeFromTm(long timestamp) {
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date(timestamp));
    }

    public static long getTmFromString(String dateString) {
        Date date = null;

        try {
            date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(dateString);
        } catch (ParseException var3) {
            var3.printStackTrace();
        }

        return date != null ? date.getTime() : 0L;
    }

    public static String getDateStringFromString(String dateString) {
        Date date = null;
        if (StringUtils.isNotBlank(dateString)) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(dateString);
            } catch (ParseException var3) {
                var3.printStackTrace();
            }

            if (date != null) {
                return toLocaleString(date, (String) null);
            }
        }

        return null;
    }

    public static String getDateStringFromStringFormat(String dateString, String dateFormat) {
        Date date = null;
        if (StringUtils.isNotBlank(dateString)) {
            try {
                date = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(dateString);
            } catch (ParseException var4) {
                var4.printStackTrace();
            }

            if (date != null) {
                return toLocaleString(date, dateFormat);
            }
        }

        return null;
    }

    public static long getMinuteTmFromString(String dateString) {
        Date date = null;

        try {
            date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).parse(dateString);
        } catch (ParseException var3) {
            var3.printStackTrace();
        }

        return date != null ? date.getTime() : 0L;
    }

    public static String toLocaleString(Date date, String dateFormat) {
        return date == null ? "" : (StringUtils.isBlank(dateFormat) ? (new SimpleDateFormat("yyyy-MM-dd")).format(date) : (new SimpleDateFormat(dateFormat)).format(date));
    }

    public static long sub(Date date1, Date date2, int unit) {
        if (date1 != null && date2 != null) {
            long milliseconds = date1.getTime() - date2.getTime();
            int divisor = -1;
            switch (unit) {
                case 5:
                    divisor = 86400000;
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                default:
                    break;
                case 11:
                    divisor = 3600000;
                    break;
                case 12:
                    divisor = '\uea60';
                    break;
                case 13:
                    divisor = 1000;
                    break;
                case 14:
                    divisor = 1;
            }

            return divisor == -1 ? -1L : milliseconds / (long) divisor;
        } else {
            return 0L;
        }
    }

    public static Date getCurrentDate() {
        return getDateStart(getCurrentTime());
    }

    public static Date parse(String date, String format) {
        try {
            SimpleDateFormat e = new SimpleDateFormat(format);
            return e.parse(date);
        } catch (Exception var3) {
            return null;
        }
    }

    /**
     * 比较两个日期之间的大小
     *
     * @param d1
     * @param d2
     * @return 前者早于后者返回true 反之false
     */
    public static boolean compareDate(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);

        int result = c1.compareTo(c2);
        if (result >= 0)
            return true;
        else
            return false;
    }

    public static Date parse(long timestamp) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp);
        return calendar.getTime();
    }

    public static Integer getMonth(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            int month = cal.get(2);
            return Integer.valueOf(month + 1);
        }
    }

    public static Integer getYear(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            return Integer.valueOf(cal.get(1));
        }
    }

    public static Integer getDay(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            return Integer.valueOf(cal.get(5));
        }
    }

    public static Date getDateStart(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(11, 0);
            calendar.set(12, 0);
            calendar.set(13, 0);
            calendar.set(14, 0);
            return calendar.getTime();
        }
    }

    public static Date getDateEnd(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(11, 23);
            calendar.set(12, 59);
            calendar.set(13, 59);
            calendar.set(14, 999);
            return calendar.getTime();
        }
    }

    public static Date getMonthStart(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(5, 1);
        calendar.set(2, month);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        calendar.set(14, 0);
        return calendar.getTime();
    }

    public static Date getMonthEnd(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(2, month);
        calendar.set(11, 23);
        calendar.set(12, 59);
        calendar.set(13, 59);
        calendar.set(5, calendar.getActualMaximum(5));
        calendar.set(14, 999);
        return calendar.getTime();
    }

    public static Date add(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    public static Date getForeverTime() {
        return parse("9999-12-31 23:59:59", "yyyy-MM-dd HH:mm:ss");
    }

    public static String getSpecifiedDayBefore(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;

        try {
            date = (new SimpleDateFormat("yyyy-MM-dd")).parse(specifiedDay);
        } catch (ParseException var5) {
            var5.printStackTrace();
        }

        c.setTime(date);
        int day = c.get(5);
        c.set(5, day - 1);
        String dayBefore = (new SimpleDateFormat("yyyy-MM-dd")).format(c.getTime());
        return dayBefore;
    }

    public static boolean isLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, calendar.get(5) + 1);
        return calendar.get(5) == 1;
    }

    public static Date getMonthStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, 1);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getMonthEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, 1);
        cal.set(11, 23);
        cal.set(12, 59);
        cal.set(13, 59);
        cal.set(14, 999);
        cal.add(2, 1);
        cal.add(5, -1);
        return cal.getTime();
    }

    public static String getWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int num = cal.get(7);
        String[] str = new String[]{"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        return str[num];
    }

    public static Date getWeekStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(7, 2);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getWeekEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(7, 1);
        cal.add(3, 1);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Integer getNextMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(2, 1);
        return Integer.valueOf(cal.get(2));
    }

    public static boolean isBetweenTime(Date date, String startTime, String endTime) {
        String[] startTimeArray = startTime.split(":");
        String[] endTimeArray = endTime.split(":");
        Calendar rangeStart = Calendar.getInstance();
        rangeStart.setTime(date);
        rangeStart.set(11, Integer.valueOf(startTimeArray[0]).intValue());
        rangeStart.set(12, Integer.valueOf(startTimeArray[1]).intValue());
        rangeStart.set(13, Integer.valueOf(startTimeArray[2]).intValue());
        Calendar rangeEnd = Calendar.getInstance();
        rangeEnd.setTime(date);
        rangeEnd.set(11, Integer.valueOf(endTimeArray[0]).intValue());
        rangeEnd.set(12, Integer.valueOf(endTimeArray[1]).intValue());
        rangeEnd.set(13, Integer.valueOf(endTimeArray[2]).intValue());
        Calendar objectDate = Calendar.getInstance();
        objectDate.setTime(date);
        return objectDate.after(rangeStart) && !objectDate.after(rangeEnd);
    }

    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }

    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 != null && cal2 != null) {
            return cal1.get(0) == cal2.get(0) && cal1.get(1) == cal2.get(1) && cal1.get(6) == cal2.get(6);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }

    public static Date[] getWeekInterval(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(2);
        cal.setTime(date);
        Calendar bgn = Calendar.getInstance();
        bgn.setFirstDayOfWeek(2);
        bgn.set(1, cal.get(1));
        bgn.set(3, cal.get(3));
        bgn.set(7, 2);
        bgn.set(11, 0);
        bgn.set(12, 0);
        bgn.set(13, 0);
        bgn.set(14, 0);
        Calendar end = Calendar.getInstance();
        end.setFirstDayOfWeek(2);
        end.set(1, cal.get(1));
        end.set(3, cal.get(3));
        end.set(7, 1);
        end.set(11, 23);
        end.set(12, 59);
        end.set(13, 59);
        end.set(14, 999);
        return new Date[]{bgn.getTime(), end.getTime()};
    }

    public static Date max(Date... dates) {
        if (ArrayUtils.isEmpty(dates)) {
            return null;
        } else {
            Date max = dates[0];

            for (int i = 1; i < dates.length; ++i) {
                Date d = dates[i];
                if (d != null && d.compareTo(max == null ? DateUtils.addDays(d, -1) : max) > 0) {
                    max = d;
                }
            }

            return max;
        }
    }

    public static Date min(Date... dates) {
        if (ArrayUtils.isEmpty(dates)) {
            return null;
        } else {
            Date min = dates[0];

            for (int i = 1; i < dates.length; ++i) {
                Date d = dates[i];
                if (d != null && d.compareTo(min == null ? DateUtils.addDays(d, 1) : min) < 0) {
                    min = d;
                }
            }

            return min;
        }
    }

    public static boolean between(Date d, Date begin, Date end) {
        return d != null && begin != null && end != null && d.compareTo(begin) >= 0 && d.compareTo(end) <= 0;
    }

    public static boolean checkFormat(String dateString, String format) {
        DateFormat formatter = new SimpleDateFormat(format);
        try {
            Date date = (Date) formatter.parse(dateString);
            return dateString.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);
        System.out.println(getWeekStart(d));
        System.out.println(getWeekEnd(d));
        System.out.println();
        System.out.println(checkFormat("2016909", DAY_FORMAT));
        System.out.println(checkFormat("20160909", DEFAULT_DATE_FORMAT));
    }
}